package cn.sylinx.redis.springboot;

import java.util.Map;
import java.util.Set;

import cn.sylinx.common.ext.res.Resource;
import cn.sylinx.common.ext.res.ResourceBlock;
import cn.sylinx.common.ext.res.ResourceHelper;
import redis.clients.jedis.Jedis;

public class BaseRedisCommand {

	protected Resource<Jedis> redisResource;
	

	public void setRedisResource(Resource<Jedis> redisResource) {
		this.redisResource = redisResource;
	}

	/**
	 * 发布
	 * 
	 * @param channel
	 * @param message
	 * @return
	 */
	public Long publish(final byte[] channel, final byte[] message) {
		return ResourceHelper.using(redisResource, new ResourceBlock<Jedis, Long>() {
			@Override
			public Long apply(Jedis resource) throws Exception {
				return resource.publish(channel, message);
			}
		});
	}

	/**
	 * 发布
	 * 
	 * @param key
	 * @param value
	 * @return
	 */
	public Long publish(final String channel, final String message) {

		return ResourceHelper.using(redisResource, new ResourceBlock<Jedis, Long>() {
			@Override
			public Long apply(Jedis resource) throws Exception {
				return resource.publish(channel, message);
			}
		});
	}

	/**
	 * redis 订阅
	 * 
	 * @param channelsWithHandlers
	 * @return
	 */
	public Void subscribeBinary(final RedisBinaryPubSub redisBinaryPubSub) {

		final byte[][] channels = redisBinaryPubSub.getChannels();

		return ResourceHelper.using(redisResource, new ResourceBlock<Jedis, Void>() {
			@Override
			public Void apply(Jedis resource) throws Exception {
				resource.subscribe(redisBinaryPubSub, channels);
				return null;
			}
		});
	}

	/**
	 * redis订阅
	 * 
	 * @param channelsWithHandlers
	 * @return
	 */
	public Void subscribe(final RedisPubSub redisPubSub) {

		final String[] channels = redisPubSub.getChannels();

		return ResourceHelper.using(redisResource, new ResourceBlock<Jedis, Void>() {
			@Override
			public Void apply(Jedis resource) throws Exception {
				resource.subscribe(redisPubSub, channels);
				return null;
			}
		});
	}

	/**
	 * 不存在则设置
	 * 
	 * @param key
	 * @param value
	 * @return
	 */
	public Long setnx(final String key, final String value) {
		return ResourceHelper.using(redisResource, new ResourceBlock<Jedis, Long>() {
			@Override
			public Long apply(Jedis resource) throws Exception {
				return resource.setnx(key, value);
			}
		});
	}

	/**
	 * hash set
	 * 
	 * @param key
	 * @param hash
	 * @return
	 */
	public String hmset(final String key, final Map<String, String> hash) {
		return ResourceHelper.using(redisResource, new ResourceBlock<Jedis, String>() {
			@Override
			public String apply(Jedis resource) throws Exception {
				return resource.hmset(key, hash);
			}
		});
	}

	/**
	 * hash set
	 * 
	 * @param key
	 * @param field
	 * @param value
	 * @return
	 */
	public Long hset(final String key, final String field, final String value) {
		return ResourceHelper.using(redisResource, new ResourceBlock<Jedis, Long>() {
			@Override
			public Long apply(Jedis resource) throws Exception {
				return resource.hset(key, field, value);
			}
		});
	}

	/**
	 * hash 获取
	 * 
	 * @param key
	 * @return
	 */
	public Map<String, String> hgetAll(final String key) {
		return ResourceHelper.using(redisResource, new ResourceBlock<Jedis, Map<String, String>>() {
			@Override
			public Map<String, String> apply(Jedis resource) throws Exception {
				return resource.hgetAll(key);
			}
		});
	}

	/**
	 * hash获取
	 * 
	 * @param key
	 * @param field
	 * @return
	 */
	public String hget(final String key, final String field) {
		return ResourceHelper.using(redisResource, new ResourceBlock<Jedis, String>() {
			@Override
			public String apply(Jedis resource) throws Exception {
				return resource.hget(key, field);
			}
		});
	}

	/**
	 * 获取键值
	 * 
	 * @param key
	 * @return
	 */
	public String get(final String key) {

		return ResourceHelper.using(redisResource, new ResourceBlock<Jedis, String>() {

			@Override
			public String apply(Jedis resource) throws Exception {
				return resource.get(key);
			}
		});
	}

	/**
	 * 设置值
	 * 
	 * @param key
	 * @param value
	 * @return
	 */
	public String set(final String key, final String value) {
		return ResourceHelper.using(redisResource, new ResourceBlock<Jedis, String>() {
			@Override
			public String apply(Jedis resource) throws Exception {
				return resource.set(key, value);
			}
		});
	}

	/**
	 * 删除键
	 * 
	 * @param key
	 * @return
	 */
	public Long del(final String key) {
		return ResourceHelper.using(redisResource, new ResourceBlock<Jedis, Long>() {
			@Override
			public Long apply(Jedis resource) throws Exception {
				return resource.del(key);
			}
		});
	}

	/**
	 * 键是否存在
	 * 
	 * @param key
	 * @return
	 */
	public Boolean exists(final String key) {
		return ResourceHelper.using(redisResource, new ResourceBlock<Jedis, Boolean>() {
			@Override
			public Boolean apply(Jedis resource) throws Exception {
				return resource.exists(key);
			}
		});
	}

	/**
	 * 设置过期时间
	 * 
	 * @param key
	 * @param seconds
	 * @return
	 */
	public Long expire(final String key, final int seconds) {
		return ResourceHelper.using(redisResource, new ResourceBlock<Jedis, Long>() {
			@Override
			public Long apply(Jedis resource) throws Exception {
				return resource.expire(key, seconds);
			}
		});
	}

	/**
	 * 设置键值，带过期时间
	 * 
	 * @param key
	 * @param seconds
	 * @param value
	 * @return
	 */
	public String setex(final String key, final int seconds, final String value) {

		return ResourceHelper.using(redisResource, new ResourceBlock<Jedis, String>() {
			@Override
			public String apply(Jedis resource) throws Exception {
				return resource.setex(key, seconds, value);
			}
		});
	}

	/**
	 * hash set
	 * 
	 * @param key
	 * @param hash
	 * @return
	 */
	public String hmset(final byte[] key, final Map<byte[], byte[]> hash) {
		return ResourceHelper.using(redisResource, new ResourceBlock<Jedis, String>() {
			@Override
			public String apply(Jedis resource) throws Exception {
				return resource.hmset(key, hash);
			}
		});
	}

	/**
	 * hash set
	 * 
	 * @param key
	 * @param field
	 * @param value
	 * @return
	 */
	public Long hset(final byte[] key, final byte[] field, final byte[] value) {
		return ResourceHelper.using(redisResource, new ResourceBlock<Jedis, Long>() {
			@Override
			public Long apply(Jedis resource) throws Exception {
				return resource.hset(key, field, value);
			}
		});
	}

	/**
	 * hash 获取
	 * 
	 * @param key
	 * @return
	 */
	public Map<byte[], byte[]> hgetAll(final byte[] key) {
		return ResourceHelper.using(redisResource, new ResourceBlock<Jedis, Map<byte[], byte[]>>() {
			@Override
			public Map<byte[], byte[]> apply(Jedis resource) throws Exception {
				return resource.hgetAll(key);
			}
		});
	}

	/**
	 * hash获取
	 * 
	 * @param key
	 * @param field
	 * @return
	 */
	public byte[] hget(final byte[] key, final byte[] field) {
		return ResourceHelper.using(redisResource, new ResourceBlock<Jedis, byte[]>() {
			@Override
			public byte[] apply(Jedis resource) throws Exception {
				return resource.hget(key, field);
			}
		});
	}

	/**
	 * 获取键值
	 * 
	 * @param key
	 * @return
	 */
	public byte[] get(final byte[] key) {
		return ResourceHelper.using(redisResource, new ResourceBlock<Jedis, byte[]>() {
			@Override
			public byte[] apply(Jedis resource) throws Exception {
				return resource.get(key);
			}
		});
	}

	/**
	 * 设置值
	 * 
	 * @param key
	 * @param value
	 * @return
	 */
	public String set(final byte[] key, final byte[] value) {
		return ResourceHelper.using(redisResource, new ResourceBlock<Jedis, String>() {
			@Override
			public String apply(Jedis resource) throws Exception {
				return resource.set(key, value);
			}
		});
	}

	/**
	 * 删除键
	 * 
	 * @param key
	 * @return
	 */
	public Long del(final byte[] key) {
		return ResourceHelper.using(redisResource, new ResourceBlock<Jedis, Long>() {
			@Override
			public Long apply(Jedis resource) throws Exception {
				return resource.del(key);
			}
		});
	}

	/**
	 * 键是否存在
	 * 
	 * @param key
	 * @return
	 */
	public Boolean exists(final byte[] key) {
		return ResourceHelper.using(redisResource, new ResourceBlock<Jedis, Boolean>() {
			@Override
			public Boolean apply(Jedis resource) throws Exception {
				return resource.exists(key);
			}
		});
	}

	/**
	 * 设置过期时间
	 * 
	 * @param key
	 * @param seconds
	 * @return
	 */
	public Long expire(final byte[] key, final int seconds) {
		return ResourceHelper.using(redisResource, new ResourceBlock<Jedis, Long>() {
			@Override
			public Long apply(Jedis resource) throws Exception {
				return resource.expire(key, seconds);
			}
		});
	}

	/**
	 * 设置键值，带过期时间
	 * 
	 * @param key
	 * @param seconds
	 * @param value
	 * @return
	 */
	public String setex(final byte[] key, final int seconds, final byte[] value) {

		return ResourceHelper.using(redisResource, new ResourceBlock<Jedis, String>() {
			@Override
			public String apply(Jedis resource) throws Exception {
				return resource.setex(key, seconds, value);
			}
		});
	}

	/**
	 * 模糊查询所有keys
	 * 
	 * @param params
	 * @return
	 */
	public Set<String> getAllKeys(final String params) {
		return ResourceHelper.using(redisResource, new ResourceBlock<Jedis, Set<String>>() {
			@Override
			public Set<String> apply(Jedis resource) throws Exception {
				return resource.keys(params);
			}
		});
	}
}
